//
//  UIButton+DFClick.m
//  FrameWork
//
//  Created by 王*风 on ****/5/9.
//

#import "UIButton+DFClick.h"
#import  <objc/runtime.h>

#define defaultInterval 0.5  //默认时间间隔
@interface UIButton ()

@property(nonatomic, strong) UIView *df_modalView;
@property(nonatomic, strong) UIActivityIndicatorView *df_spinnerView;
@property(nonatomic, strong) UILabel *df_spinnerTitleLabel;

@end


@implementation UIButton (DFClick)

static char topNameKey;
static char rightNameKey;
static char bottomNameKey;
static char leftNameKey;
static const char *UIControl_eventTimeInterval = "UIControl_eventTimeInterval";
static const char *UIControl_enventIsIgnoreEvent = "UIControl_enventIsIgnoreEvent";


/**  扩大buuton点击范围  */
- (void)df_largeEdgeWithTop:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom left:(CGFloat)left
{
    objc_setAssociatedObject(self, &topNameKey, [NSNumber numberWithFloat:top], OBJC_ASSOCIATION_COPY_NONATOMIC);
    objc_setAssociatedObject(self, &rightNameKey, [NSNumber numberWithFloat:right], OBJC_ASSOCIATION_COPY_NONATOMIC);
    objc_setAssociatedObject(self, &bottomNameKey, [NSNumber numberWithFloat:bottom], OBJC_ASSOCIATION_COPY_NONATOMIC);
    objc_setAssociatedObject(self, &leftNameKey, [NSNumber numberWithFloat:left], OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (CGRect)enlargedRect
{
    NSNumber* topEdge    = objc_getAssociatedObject(self, &topNameKey);
    NSNumber* rightEdge  = objc_getAssociatedObject(self, &rightNameKey);
    NSNumber* bottomEdge = objc_getAssociatedObject(self, &bottomNameKey);
    NSNumber* leftEdge   = objc_getAssociatedObject(self, &leftNameKey);
    
    if (topEdge && rightEdge && bottomEdge && leftEdge){
        return CGRectMake(self.bounds.origin.x - leftEdge.doubleValue,
                          self.bounds.origin.y - topEdge.doubleValue,
                          self.bounds.size.width  + leftEdge.doubleValue + rightEdge.doubleValue,
                          self.bounds.size.height + topEdge.doubleValue + bottomEdge.doubleValue);
    } else{
        return self.bounds;
    }
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    CGRect rect = [self enlargedRect];
    
    if (CGRectEqualToRect(rect, self.bounds)){
        return [super pointInside:point withEvent:event];
    }else{
        return CGRectContainsPoint(rect, point);
    }
}


- (void)df_beginSubmitting:(NSString *)title {
    [self df_endSubmitting];
    
    self.jk_submitting = @YES;
    self.hidden = YES;
    
    self.jk_modalView = [[UIView alloc] initWithFrame:self.frame];
    self.jk_modalView.backgroundColor =
    [self.backgroundColor colorWithAlphaComponent:0.6];
    self.jk_modalView.layer.cornerRadius = self.layer.cornerRadius;
    self.jk_modalView.layer.borderWidth = self.layer.borderWidth;
    self.jk_modalView.layer.borderColor = self.layer.borderColor;
    
    CGRect viewBounds = self.jk_modalView.bounds;
    self.jk_spinnerView = [[UIActivityIndicatorView alloc]
                        initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
    self.jk_spinnerView.tintColor = self.titleLabel.textColor;
    
    CGRect spinnerViewBounds = self.jk_spinnerView.bounds;
    self.jk_spinnerView.frame = CGRectMake(
                                        15, viewBounds.size.height / 2 - spinnerViewBounds.size.height / 2,
                                        spinnerViewBounds.size.width, spinnerViewBounds.size.height);
    self.jk_spinnerTitleLabel = [[UILabel alloc] initWithFrame:viewBounds];
    self.jk_spinnerTitleLabel.textAlignment = NSTextAlignmentCenter;
    self.jk_spinnerTitleLabel.text = title;
    self.jk_spinnerTitleLabel.font = self.titleLabel.font;
    self.jk_spinnerTitleLabel.textColor = self.titleLabel.textColor;
    [self.jk_modalView addSubview:self.jk_spinnerView];
    [self.jk_modalView addSubview:self.jk_spinnerTitleLabel];
    [self.superview addSubview:self.jk_modalView];
    [self.jk_spinnerView startAnimating];
}

- (void)df_endSubmitting {
    if (!self.isJKSubmitting.boolValue) {
        return;
    }
    
    self.jk_submitting = @NO;
    self.hidden = NO;
    
    [self.jk_modalView removeFromSuperview];
    self.jk_modalView = nil;
    self.jk_spinnerView = nil;
    self.jk_spinnerTitleLabel = nil;
}

- (NSNumber *)isJKSubmitting {
    return objc_getAssociatedObject(self, @selector(setJk_submitting:));
}

- (void)setJk_submitting:(NSNumber *)submitting {
    objc_setAssociatedObject(self, @selector(setJk_submitting:), submitting, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
}

- (UIActivityIndicatorView *)jk_spinnerView {
    return objc_getAssociatedObject(self, @selector(setJk_spinnerView:));
}

- (void)setJk_spinnerView:(UIActivityIndicatorView *)spinnerView {
    objc_setAssociatedObject(self, @selector(setJk_spinnerView:), spinnerView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIView *)jk_modalView {
    return objc_getAssociatedObject(self, @selector(setJk_modalView:));

}

- (void)setJk_modalView:(UIView *)modalView {
    objc_setAssociatedObject(self, @selector(setJk_modalView:), modalView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UILabel *)jk_spinnerTitleLabel {
    return objc_getAssociatedObject(self, @selector(setJk_spinnerTitleLabel:));
}

- (void)setJk_spinnerTitleLabel:(UILabel *)spinnerTitleLabel {
    objc_setAssociatedObject(self, @selector(setJk_spinnerTitleLabel:), spinnerTitleLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}



- (UIEdgeInsets)jk_touchAreaInsets
{
    return [objc_getAssociatedObject(self, @selector(jk_touchAreaInsets)) UIEdgeInsetsValue];
}


#pragma mark -  禁止按钮连续单击

- (NSTimeInterval)timeInterval{
    return [objc_getAssociatedObject(self,_cmd)doubleValue];
}
 
- (void)setTimeInterval:(NSTimeInterval)timeInterval{
    objc_setAssociatedObject(self,@selector(timeInterval),@(timeInterval),OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
 
- (void)setIsIgnoreEvent:(BOOL)isIgnoreEvent{
    objc_setAssociatedObject(self,@selector(isIgnoreEvent),@(isIgnoreEvent),OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
 
- (BOOL)isIgnoreEvent{
    return [objc_getAssociatedObject(self,_cmd)boolValue];
}
 
- (void)resetState{
    [self setIsIgnoreEvent:NO];
}
+ (void)load{
       static dispatch_once_t onceToken;
       dispatch_once(&onceToken, ^{
           SEL selA = @selector(sendAction:to:forEvent:);
           SEL selB = @selector(mySendAction:to:forEvent:);
           Method methodA = class_getInstanceMethod(self, selA);
           Method methodB = class_getInstanceMethod(self, selB);
           //将methodB的实现添加到系统方法中也就是说将methodA方法指针添加成方法methodB的返回值表示是否添加成功
           BOOL isAdd = class_addMethod(self, selA,method_getImplementation(methodB),method_getTypeEncoding(methodB));
           //添加成功了说明本类中不存在methodB所以此时必须将方法b的实现指针换成方法A的，否则b方法将没有实现。
           if(isAdd) {
               class_replaceMethod(self, selB,method_getImplementation(methodA),method_getTypeEncoding(methodA));
           }else{
               //添加失败了说明本类中有methodB的实现，此时只需要将methodA和methodB的IMP互换一下即可。
               method_exchangeImplementations(methodA, methodB);
           }
       });
   }
    
   - (void)mySendAction:(SEL)action to:(id)target forEvent:(UIEvent*)event{
       if([NSStringFromClass(self.class) isEqualToString:@"UIButton"]) {
           self.timeInterval = self.timeInterval == 0 ? defaultInterval:self.timeInterval;
           if(self.isIgnoreEvent){
               return;
           }else if(self.timeInterval > 0){
               [self performSelector:@selector(resetState)withObject:nil afterDelay:self.timeInterval];
           }
       }
       //此处methodA和methodB方法IMP互换了，实际上执行sendAction；所以不会死循环
       self.isIgnoreEvent = YES;
       [self mySendAction:action to:target forEvent:event];
   }

@end
